package components;

import javax.swing.Timer;

import main.Main;

import java.awt.event.*;
import java.io.IOException;
import java.util.logging.FileHandler;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.logging.SimpleFormatter;

public class PumpController {
	public enum PumpStatus {Stopped,Running,Paused};
	public enum BatteryStatus {Normal,Warning,Low,Depleted};

	private PumpStatus pumpStatus;
	private PowerManager pm;
	private InsulinManager insulinManager;
	
	private Timer dosageTimer;
	private Timer batteryTimer;
	private Timer bolusTimer;
	Logger log;
	
	public float pumpDosageTotal = 0;
	
	public PumpController() {
		log = Logger.getLogger("log");
		FileHandler fh = null;
		try {
			fh = new FileHandler("logfile.txt");
			log.addHandler(fh);
		} catch (SecurityException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		SimpleFormatter formatter = new SimpleFormatter();
		fh.setFormatter(formatter);
		
		pumpStatus = PumpStatus.Stopped;
		pm = new PowerManager();
		insulinManager = new InsulinManager();
		dosageTimer = new Timer(5000, dosageActionListener);	
		batteryTimer = new Timer(3000, batteryActionListener);
		batteryTimer.start();
		
		
		//TODO: Add initialization procedure. Remove temp print below.
		
		log.info("Pump has booted up.");
	}
	
	public void setRunning() {
		pumpStatus = PumpStatus.Running;
		dosageTimer.start();

		log.info("Pump has started running.");
	}

	public void setPaused() {
		pumpStatus = PumpStatus.Paused;
		if (dosageTimer != null && dosageTimer.isRunning()) {
			dosageTimer.stop();	// Stop the dosage timer if it is running
		}

		log.info("Pump has paused.");
	}

	public void setStopped() {
		pumpStatus = PumpStatus.Stopped;
		if (dosageTimer != null && dosageTimer.isRunning()) {
			dosageTimer.stop();	// Stop the dosage timer if it is running
			dosageTimer = null;
		}

		log.info("Pump has stopped.");
	}
	
	public void setOff() {
		pumpStatus = PumpStatus.Stopped;
		if (dosageTimer != null && dosageTimer.isRunning()) {
			dosageTimer.stop();	// Stop the dosage timer if it is running
			dosageTimer = null;
		}
		// TODO: Add shutdown procedure
		log.info("Pump is shutting down...");
	}
		
	public InsulinManager getInsulinManager() {
		return insulinManager;
	}

	public int getBatteryLevel() {
		return pm.getBatteryLevel();
	}

	public void setBatteryLevel(int batteryLevel) {
		pm.setBatteryLevel(batteryLevel);
	}
	
	public BatteryStatus getBatteryStatus() {
		return pm.getBatteryStatus();
	}
	
	public Timer getDosageTimer() {
		return dosageTimer;
	}

	public Timer getBatteryTimer() {
		return batteryTimer;
	}
	
	
	
	//############# ActionListeners #############
	
	
	
	// Executes at every timeout
	ActionListener dosageActionListener = new ActionListener() {
		public void actionPerformed(ActionEvent evt) {
			// TODO: Supply dosage to patient. Remove temp print below.
			pumpDosageTotal += ((float)insulinManager.getCurrentBasalRate()*5)/360;
			log.info("Basal profile dose administered. (Total = " + pumpDosageTotal+")");
		}
	};
	
	// Executes at every timeout
	ActionListener batteryActionListener = new ActionListener() {
		public void actionPerformed(ActionEvent evt) {
				pm.decrementBatteryLevel();
		}
	};
	

	public Timer getBolusTimer() {
		return bolusTimer;
	}

	public void setBolusTimer(Timer bolusTimer) {
		this.bolusTimer = bolusTimer;
	}
}